﻿using FlexFlow.Model;
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow.Runtime
{
    /// <summary>
    /// 系统权限定义
    /// </summary>
    public static class SystemPermissions
    {
        /// <summary>
        /// 表示流程进入权限定义
        /// </summary>
        public static PermissionDefine ProcessEnterPermission { get; private set; }

        static SystemPermissions()
        {
            ProcessEnterPermission = new PermissionDefine()
            {
                Identity = Guid.Parse("FB2B306D-0D96-4F39-A197-F5DC4D88E992"),
                Name = "发起流程权限",
                Description = "表示指定成员是否具有发起流程的权限",
                Type = "系统权限",
                DefaultValue = false
            };
        }
    }
    /// <summary>
    /// 表示权限管理器
    /// </summary>
    public class PermissionManager : ManagerBase
    {
        /// <summary>
        /// 获取或设置默认的权限管理器
        /// </summary>
        public static PermissionManager Default { get; set; }
        /// <summary>
        /// 设置指定用户或者组织机构的权限
        /// </summary>
        /// <param name="permission">
        /// 权限定义
        /// </param>
        /// <param name="users">
        /// 要设置的用户列表
        /// </param>
        /// <param name="orgs">
        /// 要设置的组织机构列表
        /// </param>
        /// <param name="tag">
        /// 要设置的权限的附加信息
        /// </param>
        /// <param name="permissionValue">
        /// 权限值
        /// </param>
        /// <returns>
        /// 操作结果
        /// </returns>
        public OperateResult SetPermission(PermissionDefine perDef, Guid[] users, Guid[] orgs, string tag, bool permissionValue)
        {
            //尝试取得已经定义的用户权限
            UserPermission per = this.Components.UserPermissionProvider.GetByDefineId(perDef.Identity, tag);
            string replaceUsers = null;
            string replaceOrgs = null;
            //用户权限尚未定义
            if (per == null)
            {
                //定义权限
                per = this.Components.UserPermissionProvider.Create();
                per.Value = !perDef.DefaultValue;
                per.DefineId = perDef.Identity;
                if (permissionValue != perDef.DefaultValue)
                {
                    if (users != null)
                    {
                        StringBuilder sb = new StringBuilder(Guid.Empty.ToString().Length * (users.Length + 1));
                        foreach (var user in users)
                            sb.Append(user + ",");
                        replaceUsers = sb.ToString();
                    }
                    if (orgs != null)
                    {
                        StringBuilder sb = new StringBuilder(Guid.Empty.ToString().Length * (orgs.Length + 1));
                        foreach (var org in orgs)
                            sb.Append(org + ",");
                        replaceOrgs = sb.ToString();
                    }
                }
                per.Users = replaceUsers;
                per.Organizations = replaceOrgs;
                per.Tag = tag;
                if (!this.Components.UserPermissionProvider.Add(per))
                {
                    return new OperateResult()
                    {
                        ResultCode = 0x120301,
                        Message = "创建权限失败"
                    };
                }
            }
            //用户权限已经定义，修改其中的用户列表与组织机构列表
            HashSet<string> userSet = per.Users == null ? new HashSet<string>() : new HashSet<string>(per.Users.Split(','));
            HashSet<string> orgSet = per.Organizations == null ? new HashSet<string>() : new HashSet<string>(per.Organizations.Split(','));
            if (permissionValue == perDef.DefaultValue)
            {
                if (users != null)
                    foreach (var user in users)
                        userSet.Remove(user.ToString());

                if (orgs != null)
                    foreach (var org in orgs)
                        orgSet.Remove(org.ToString());
            }
            else
            {
                if (users != null)
                    foreach (var user in users)
                        userSet.Add(user.ToString());

                if (orgs != null)
                    foreach (var org in orgs)
                        orgSet.Remove(org.ToString());
            }
            if (users != null)
            {
                StringBuilder sb = new StringBuilder(Guid.Empty.ToString().Length * (userSet.Count + 1));
                foreach (var user in userSet)
                    sb.Append(user + ",");
                replaceUsers = sb.ToString();
            }
            if (orgs != null)
            {
                StringBuilder sb = new StringBuilder(Guid.Empty.ToString().Length * (orgSet.Count + 1));
                foreach (var org in orgs)
                    sb.Append(org + ",");
                replaceOrgs = sb.ToString();
            }
            if (!this.Components.UserPermissionProvider.Update(per.Identity, replaceUsers, replaceOrgs))
            {
                return new OperateResult()
                {
                    ResultCode = 0x120302,
                    Message = "更新权限失败"
                };
            }
            return OperateResult.SuccessResult();
        }
        /// <summary>
        /// 检查指定用户具有指定名称的权限值是否等于预期
        /// </summary>
        /// <param name="userId">
        /// 用户Id
        /// </param>
        /// <param name="permissionName">
        /// 权限名称
        /// </param>
        /// <param name="permissionType">
        /// 权限类型
        /// </param>
        /// <param name="permissionTag">
        /// 权限的备注信息
        /// </param>
        /// <param name="permissionValue">
        /// 权限值
        /// </param>
        /// <returns>
        /// 操作结果，其中的Tag为一个布尔值，表示当前用户的权限值是否等于预期
        /// </returns>
        public OperateResult CheckPermission(Guid userId, string permissionName, string permissionType, string permissionTag, bool permissionValue)
        {
            PermissionDefine perDef = this.Components.PermissionDefineProvider.Get(permissionName, permissionType);
            if (perDef == null)
            {
                return new OperateResult() { ResultCode = 0x120201, Message = "权限不存在" };
            }
            else
            {
                return CheckPermission(userId, perDef, permissionTag, permissionValue);
            }
        }
        /// <summary>
        /// 检查指定用户具有指定名称的权限值是否等于预期
        /// </summary>
        /// <param name="userId">
        /// 用户Id
        /// </param>
        /// <param name="permissionDef">
        /// 权限定义
        /// </param>
        /// <param name="permissionTag">
        /// 权限备注
        /// </param>
        /// <param name="permissionValue">
        /// 预期的权限值
        /// </param>
        /// <returns>
        /// 操作结果，其中的Tag为一个布尔值，表示当前用户的权限值是否等于预期
        /// </returns>
        public OperateResult CheckPermission(Guid userId, PermissionDefine permissionDef, string permissionTag, bool permissionValue)
        {
            Guid orgId = default(Guid);
            LoginedUserInfo logUser = this.Components.OnlineUserPool.GetLoginedUserInfoByUid(userId);
            if (logUser != null)
                orgId = logUser.OrganizationId;
            else
            {
                User user = this.Components.UserProvider.Get(userId);
                if (user == null)
                {
                    return new OperateResult() { ResultCode = 0x120101, Message = "用户不存在" };
                }
            }
            if (permissionValue == permissionDef.DefaultValue)
            {
                return OperateResult.SuccessResult(true);
            }
            UserPermission permission = this.Components.UserPermissionProvider.Get(permissionDef.Identity, userId, orgId, permissionTag, permissionValue);
            if (permission == null)
            {
                return OperateResult.SuccessResult(false);
            }
            else
            {
                return OperateResult.SuccessResult(true);
            }
        }

        static PermissionManager()
        {
            Default = new PermissionManager();
        }
    }
}
